Add a new snippet to demonstrate drawing to different devices#3065
Add a new snippet to demonstrate drawing to different devices#3065laeubi merged 1 commit intoeclipse-platform:masterfrom
Conversation
36a6788 to
fc466e9
Compare
|
@Phillipus would be interesting to see the behavior on Mac! Beside this Snippets will not be tested by the build so we can merge... (Jenkins hang again). |
DPI Reporting Issue on LinuxProblemWhen drawing physical measurements on screen (e.g., a 10cm box), there's a significant mismatch between expected and actual size on Linux/GTK. The reported DPI (96) doesn't match the physical DPI (~162), causing drawings to appear ~1.7x smaller than intended. Observed Behavior
A 10cm box drawn at 96 DPI = 378 pixels, but physically measures only ~5.9cm on screen. Root Cause
The physical monitor dimensions are available via Why Printing WorksPrinters report their true physical DPI directly, so there's no mismatch between reported and actual DPI. Proposed SolutionAdd a new // New API - returns physical DPI based on monitor size in mm
Point physicalDPI = display.getPhysicalDPI();
// Existing API - unchanged, returns logical/system DPI (96)
Point logicalDPI = display.getDPI();This approach:
|
DPI Mismatch Analysis: Screen vs Printer vs PDF on WindowsProblem SummaryWhen drawing a box intended to be exactly 10 cm on screen, printer, and PDF:
The on-screen rendering is off by a factor of ~0.61 (61% of intended size). Root Cause: Logical DPI ≠ Physical DPIMeasured Values on This System
The Core IssueWindows The ratio between logical and physical DPI determines the error factor: A box computed for 10 cm at 96 DPI produces 378 pixels, but 378 pixels on a Why Printers Are CorrectFor printers, Why PDF Is Correct
// PDFDocument.internal_new_GC():
float scaleX = (float)(printerDpiX / POINTS_PER_INCH); // 600/72 = 8.333
OS.SetWorldTransform(handle, new float[]{scaleX, 0, 0, scaleY, 0, 0});The PDF coordinate system is defined in terms of physical inches (72 points/inch), Detailed DPI Flow in SWT (Windows)Screen Path:
|
| Monitor | Resolution | Physical Size | Physical DPI | At 100% Scaling | Error Factor |
|---|---|---|---|---|---|
| 14" laptop | 1920×1080 | 31×17 cm | ~158 | 96 reported | 0.61 |
| 24" desktop | 1920×1080 | 53×30 cm | ~92 | 96 reported | 1.04 |
| 27" 4K | 3840×2160 | 60×34 cm | ~163 | 96 reported | 0.59 |
| 13" MacBook-like | 2560×1600 | 29×18 cm | ~227 | 96 reported | 0.42 |
The error varies wildly depending on monitor size and resolution. Only a
~24" 1080p monitor happens to have physical DPI close to 96.
At 150% Windows Scaling on This 14" Laptop
Logical DPI: 144, Physical DPI: 158
Box: 378 logical × 1.5 = 567 physical pixels
Size: 567 / 158 × 25.4 = 91.1 mm (still not 100mm, but closer)
For exact physical correctness at 158 DPI, Windows scaling would need to be
165% (158/96 × 100%), which is not a standard option.
This Is a Fundamental Platform Limitation
- Windows:
LOGPIXELSX= scaling preference, not physical measurement - Linux/GTK:
gdk_screen_get_resolution()typically returns 96 - macOS: Retina displays report 72 DPI (1× logical), non-Retina report 72 too
No mainstream desktop OS provides a reliable API for the true physical DPI of a
monitor. The HORZSIZE/VERTSIZE values from GetDeviceCaps() (based on monitor
EDID data) can approximate it but are often inaccurate.
Proposed Solutions
Solution 1: Calculate Physical DPI from EDID Data (Best Effort)
SWT could provide a method to estimate the physical DPI using GetDeviceCaps():
// In Display.java or a utility class:
public Point getPhysicalDPI() {
long hDC = internal_new_GC(null);
int horzRes = OS.GetDeviceCaps(hDC, OS.HORZRES); // pixels
int vertRes = OS.GetDeviceCaps(hDC, OS.VERTRES); // pixels
int horzSize = OS.GetDeviceCaps(hDC, OS.HORZSIZE); // mm (from EDID)
int vertSize = OS.GetDeviceCaps(hDC, OS.VERTSIZE); // mm (from EDID)
internal_dispose_GC(hDC, null);
int physDpiX = (int) Math.round(horzRes * 25.4 / horzSize);
int physDpiY = (int) Math.round(vertRes * 25.4 / vertSize);
return new Point(physDpiX, physDpiY);
}|
To summarize, my intend to really get (about) 10cm on screen is probably wrong and the snippet needs to be enhanced by checking that logical DPI is correctly transformed to physical DPI during |
|
@Phillipus thanks yes I need to sort out some issues systematically that's why I created the snippets now as I noticed the sizing issue :-\ |



This is how it looks like
This is currently waiting for
because a
PDFDocumentis not aDeviceit does not have agetDPI()but needs one if one wants to translate between page size and actual drawing points.